#include "Uart_Anayle.h"


#include "ringqueue.h"

#define FINDDATA_ELEM_BUFF_LEN (250)
#define PT_TIMEROUT_TICK (20)
#define PT_FRAME_BLEMODE_MIN_LEN (5)





typedef struct{
   uint32_t FindElemTick;
   uint8_t DataBuff[FINDDATA_ELEM_BUFF_LEN];
   uint16_t DataIndex;
   uint8_t UnitTabSel;
   uint8_t AnayleCnt;
}PKT_UintInfo_t;

typedef struct{
    uint8_t ReadBuff[FINDDATA_ELEM_BUFF_LEN];
    uint32_t ReadLen;
}PKT_ReadBuffUart_t;

typedef struct{
    uint8_t PKT_Head0;
    uint8_t PKT_Head1;
    uint8_t PKT_Len;
}PKT_HeadBlePt_t;

typedef struct{
  uint8_t (*PKTHeadCb)(PKT_UintInfo_t* PktUint);
  uint8_t (*PKTTailCb)(PKT_UintInfo_t* PktUint);
  uint8_t (*PKTLoadCb)(uint8_t*Pbuff,uint8_t PLen);
}PKT_HandlerSet_t;

static const PKT_HeadBlePt_t s_BleCtrlCmdHeadTab={
    0xA5,0xC0,0,
};

static uint8_t _PKTHead_BleCtrlCmdCheck(PKT_UintInfo_t* PktUint);
static uint8_t _PKTTail_BleCtrlCmdCheck(PKT_UintInfo_t* PktUint);
static uint8_t _PKTLoad_BleCtrlCmdPT(uint8_t* PBuff,uint8_t PLen);


static const PKT_HandlerSet_t s_PKT_HandlerSetTab[]={
     {
         _PKTHead_BleCtrlCmdCheck,
         _PKTTail_BleCtrlCmdCheck,
         _PKTLoad_BleCtrlCmdPT,
     },
};



static PKT_ReadBuffUart_t s_PKT_ReadBuff;
static PKT_UintInfo_t s_PKT_UnitInfoTx;



static uint8_t _UartFrame_Extra(PKT_UintInfo_t*PKT_Unit)
{
     volatile uint32_t i,j;
     uint8_t RetVal=0;
     uint8_t LoadRetVal=0;
     if((Hal_SysTick_Get()-PKT_Unit->FindElemTick)>=PT_TIMEROUT_TICK)
     {
          PKT_Unit->DataIndex=0;
          PKT_Unit->FindElemTick=Hal_SysTick_Get();
          return 0;
     }

     if(0==UartRxBuffer_Length())
     {
         return 0;
     }

     UartRxBuffer_BlockOut((uint8_t*)&s_PKT_ReadBuff.ReadBuff[0],   ///  ?????
                           FINDDATA_ELEM_BUFF_LEN,
                           &s_PKT_ReadBuff.ReadLen);


     for(i=0;i<s_PKT_ReadBuff.ReadLen;i++)
     {
         PKT_Unit->DataBuff[PKT_Unit->DataIndex++]=s_PKT_ReadBuff.ReadBuff[i];
         for(j=0;j<(sizeof(s_PKT_HandlerSetTab)/sizeof(PKT_HandlerSet_t));j++)  //   ??????
         {
            if(s_PKT_HandlerSetTab[j].PKTHeadCb(PKT_Unit)>0){                  ///  ???????????????????
                 break;
             }
         }
         if(j>=(sizeof(s_PKT_HandlerSetTab)/sizeof(PKT_HandlerSet_t)))      ///  ????????????????
         {
            PKT_Unit->DataIndex=0;
            continue;
         }
         RetVal=s_PKT_HandlerSetTab[j].PKTTailCb(PKT_Unit);    //????
         if(2==RetVal){                                        ///  ??????
            continue;
         }
         if(1==RetVal){                                         ///  ??????,???????
            LoadRetVal=s_PKT_HandlerSetTab[j].PKTLoadCb(&PKT_Unit->DataBuff[0],PKT_Unit->DataIndex);
            PKT_Unit->DataIndex=0;
         }else if(3==RetVal){
            PKT_Unit->DataIndex=0;
         }
     }
     if(s_PKT_ReadBuff.ReadLen>0){
        PKT_Unit->FindElemTick=Hal_SysTick_Get();        //?????
        PKT_Unit->AnayleCnt=0;
     }
    return 1;
}

static uint8_t _PKTTail_SumCheck(uint8_t*PBuff,uint8_t PLen,uint8_t CheckVal)
{
    uint8_t CheckSum=0;
    uint16_t i;
    CheckSum=0;
    for(i=0;i<PLen;i++)
    {
       CheckSum+=PBuff[i];
    }
    if(CheckSum==CheckVal)
    {
       return 1;
    }

    return 0;
}


static uint8_t _PKTHead_BleCtrlCmdCheck(PKT_UintInfo_t* PktUint)
{    
     uint16_t i;     
     uint8_t* DataPtr;
     uint8_t HeadCheckLen=0;
     if(PktUint->DataIndex==0)
     {
        return 0;
     }
     DataPtr=(uint8_t*)&s_BleCtrlCmdHeadTab;
     if(PktUint->DataIndex>=sizeof(s_BleCtrlCmdHeadTab)){
         HeadCheckLen=sizeof(s_BleCtrlCmdHeadTab);
     }else{
         HeadCheckLen=PktUint->DataIndex;
     }
     for(i=0;i<HeadCheckLen;i++)
     {
         if((PktUint->DataBuff[i]!=DataPtr[i])&&(DataPtr[i]!=0x00))
         {
            break;
         }
     }
     if(i!=HeadCheckLen)
     {
        return 0;
     }
     if(PktUint->DataIndex>=sizeof(PKT_HeadBlePt_t))
     {
        return 1;
     }
     return 2;
}

static uint8_t _PKTTail_BleCtrlCmdCheck(PKT_UintInfo_t* PktUint)
{
      PKT_HeadBlePt_t* Ptr_PKTHeadCtrl;
      uint16_t FrameLen=0;
     if(PktUint->DataIndex<PT_FRAME_BLEMODE_MIN_LEN)
      {
         return 0;
      }
      if(PktUint->DataIndex>=FINDDATA_ELEM_BUFF_LEN)
      {
           return 3;
      }
      Ptr_PKTHeadCtrl=(PKT_HeadBlePt_t*)&PktUint->DataBuff[0];
      FrameLen=Ptr_PKTHeadCtrl->PKT_Len;
      
      if((FrameLen)>=FINDDATA_ELEM_BUFF_LEN)
      {
         return 3;
      }
      
      if(PktUint->DataIndex<(FrameLen))
      {
         return 2;
      }
      if((FrameLen)==PktUint->DataIndex)
      {
         if(_PKTTail_SumCheck(&PktUint->DataBuff[0],PktUint->DataIndex-1,PktUint->DataBuff[PktUint->DataIndex-1]))
         {
            return 1;
         }
      }
      return 3;
}


static uint8_t _PKTLoad_BleCtrlCmdPT(uint8_t* PBuff,uint8_t PLen)
{
     return UartCmd_Load(PBuff,PLen); 
}


void UartAnayle_RxPoll(void)
{

     _UartFrame_Extra(&s_PKT_UnitInfoTx);


}








